﻿using DependencyAnalysis.DataModel;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PrinciplesP = DependencyAnalysis.Principles;

namespace UnitTests.Principles
{
    [TestClass]
    public class AcyclicDependenciesPrincipleTest
    {
        private IDependencyModel _dependencyModel;

        [TestInitialize]
        public void Initialize()
        {
            var descriptor = DependencyModelTest.BuildDependencyDescriptor(1, 2, true, false);
            _dependencyModel = new DependencyModel();
            _dependencyModel.Add(descriptor);
            descriptor = DependencyModelTest.BuildDependencyDescriptor(1, 3, true, false);
            _dependencyModel.Add(descriptor);
            descriptor = DependencyModelTest.BuildDependencyDescriptor(2, 3, true, false);
            _dependencyModel.Add(descriptor);
            descriptor = DependencyModelTest.BuildDependencyDescriptor(3, 4, true, false);
            _dependencyModel.Add(descriptor);
            descriptor = DependencyModelTest.BuildDependencyDescriptor(4, 5, true, false);
            _dependencyModel.Add(descriptor);
            descriptor = DependencyModelTest.BuildDependencyDescriptor(5, 6, true, false);
            _dependencyModel.Add(descriptor);
        }

        [TestMethod]
        public void WhenNoCyclesThenCycleCountIsZero()
        {
            Assert.AreEqual(0, PrinciplesP.AcyclicDependencies(_dependencyModel).Count);
        }

        [TestMethod]
        public void WhenThereIsOneBidirectionalDependencyThenCycleCountIsOne()
        {
            var descriptor = DependencyModelTest.BuildDependencyDescriptor(3, 2, true, false);
            _dependencyModel.Add(descriptor);

            Assert.AreEqual(1, PrinciplesP.AcyclicDependencies(_dependencyModel).Count);
        }

        [TestMethod]
        public void WhenThereIsOneBidirectionalDependencyThenTheCycleLengthIsTwo()
        {
            var descriptor = DependencyModelTest.BuildDependencyDescriptor(3, 2, true, false);
            _dependencyModel.Add(descriptor);

            Assert.AreEqual(2, PrinciplesP.AcyclicDependencies(_dependencyModel)[0].Count);
        }

        [TestMethod]
        public void WhenThereIsOneIndirectCycleThenCycleCountIsOne()
        {
            var descriptor = DependencyModelTest.BuildDependencyDescriptor(6, 4, true, false);
            _dependencyModel.Add(descriptor);

            Assert.AreEqual(1, PrinciplesP.AcyclicDependencies(_dependencyModel).Count);
        }

        [TestMethod]
        public void WhenThereIsOneIndirectCycleWithOneHopThenCycleLengthIsThree()
        {
            var descriptor = DependencyModelTest.BuildDependencyDescriptor(6, 4, true, false);
            _dependencyModel.Add(descriptor);

            Assert.AreEqual(3, PrinciplesP.AcyclicDependencies(_dependencyModel)[0].Count);
        }

        [TestMethod]
        public void WhenThereIsOneBidirectionalAndOneIndirectCycleThenCycleCountIsTwo()
        {
            var descriptor = DependencyModelTest.BuildDependencyDescriptor(3, 2, true, false);
            _dependencyModel.Add(descriptor); 
            descriptor = DependencyModelTest.BuildDependencyDescriptor(6, 4, true, false);
            _dependencyModel.Add(descriptor);

            Assert.AreEqual(2, PrinciplesP.AcyclicDependencies(_dependencyModel).Count);
        }
    }
}
